/*
 * 版权所有 (C) 2015 知启蒙(ZHIQIM) 保留所有权利。[遇见知启蒙，邂逅框架梦]
 * 
 * https://zhiqim.org/project/zhiqim_framework/zhiqim_kernel.htm
 *
 * Zhiqim Kernel is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *          http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */
package org.zhiqim.kernel.xml;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

import org.zhiqim.kernel.annotation.AnAlias;
import org.zhiqim.kernel.constants.AsciiConstants;
import org.zhiqim.kernel.util.Strings;
import org.zhiqim.kernel.util.Validates;
import org.zhiqim.kernel.xml.annotation.XmlClassTag;
import org.zhiqim.kernel.xml.annotation.XmlFieldNoGroup;

/**
 * Xms相关工具类
 *
 * @version v1.1.2 @author zouzhigang 2015-8-21 新建与整理
 */
@AnAlias("Xmls")
public class Xmls extends Xmlx implements AsciiConstants
{
    /********************************************************/
    //提供静态的toString和toObject方法,取标准XML参数
    /********************************************************/
    
    /**
     * 默认的对象转XML字符串方法，不同的参数请单独使用Xml类
     * 
     * @param obj   对象
     * @return      返回XML字符串
     */
    public static String toString(Object obj)
    {
        return Xml.xml.toString(obj);
    }
    
    /**
     * 默认的XML字符串转换成对象，不同的参数请单独使用Xml类
     * 
     * @param str   XML字符串
     * @param clazz 转换成对象的类
     * @return      对应的对象
     */
    public static <T> T toObject(String str, Class<T> clazz)
    {
        return Xml.xml.toObject(str, clazz);
    }
    
    /********************************************************/
    //以下XML注解相关
    /********************************************************/
    
    /**
     * 获取类的XML标志，优先查@XmlTag，没有取@Alias，再没有取没有包结构的短类名
     * 
     * @param clazz 类结构
     * @return      XML标记，没有取短类名
     */
    public static String getXmlClassTag(Class<?> clazz)
    {
        if (clazz == null)
            return null;
        
        XmlClassTag xmlTag = clazz.getAnnotation(XmlClassTag.class);
        if (xmlTag != null && !Validates.isEmptyBlank(xmlTag.value()))
            return xmlTag.value().trim();
        
        AnAlias alias = clazz.getAnnotation(AnAlias.class);
        if (alias != null && !Validates.isEmptyBlank(alias.value()[0]))
            return alias.value()[0].trim();
        
        return Strings.lastIndexOfString(clazz.getName(), ".");
    }
    
    /**
     * 判断XMLList是否需要组号
     * 
     * @param field 字段
     * @return      如果实现XmlFieldNoGroup则不需要，默认需要
     */
    public static boolean hasXmlFieldGroup(Field field)
    {
        return !field.isAnnotationPresent(XmlFieldNoGroup.class);
    }
    
    /********************************************************/
    //以下解析XML时需要的字符串分析方法
    /********************************************************/
    
    /**
     * 获取XML中属性列表
     * 
     * @param xml   XML字符串
     * @param name  字段名称
     * @return      XML子段列表
     */
    public static List<String> getXmlFieldList(String xml, String name)
    {
        List<String> list = new ArrayList<String>();
        
        String lField = "<"+name+">";
        String rField = "</"+name+">";
        int rLen = rField.length();
        
        for(int iLeft=xml.indexOf(lField);iLeft!=-1;iLeft=xml.indexOf(lField))
        {
            int iRight = xml.indexOf(rField, iLeft);
            if (iRight == -1)
                break;
            
            list.add(xml.substring(iLeft, iRight+rLen));
            xml = xml.substring(iRight+rLen);
        }
        
        return list;
    }
    
    /** 读取XML中字段的值，允许没有field时返回空字符串 */
    public static String getXmlField(String xml, String field)
    {
        if (xml.length() < field.length() * 2 + 5)
            return null;
        
        String lField = "<"+field+">";
        String rField = "</"+field+">";
        int iLeft = xml.indexOf(lField);
        int iRight = xml.indexOf(rField);
        if (iLeft == -1 && iRight == -1)
            return null;
        
        if ((iLeft == -1 && iRight != -1) || (iLeft != -1 && iRight == -1))
            return null;
        
        int valueLen = iRight - iLeft - lField.length();
        if (valueLen <= 0)
            return null;
        
        return xml.substring(iLeft + lField.length(), iRight);
    }
    
    /** 读取XML中字段的int值 */
    public static int getXmlInt(String xml, String field) throws Exception
    {
        if (xml.length() < field.length() * 2 + 5)
        {
            throw new Exception("xml tag #"+field+"# format error");
        }

        String lField = "<"+field+">";
        String rField = "</"+field+">";
        int iLeft = xml.indexOf(lField);
        int iRight = xml.indexOf(rField);
        if (iLeft == -1 || iRight == -1)
        {
            throw new Exception("xml tag #"+field+"# format error");
        }
        
        int valueLen = iRight - iLeft;
        if (valueLen < 1)//nubmer不允许为空
        {
            throw new Exception("xml tag #"+field+"# format error");
        }
        
        String valueInt = xml.substring(iLeft + lField.length(), iRight);
        if (!Validates.isInteger(valueInt))
        {
            throw new Exception("xml tag #"+field+"# format error");
        }
        
        return Integer.parseInt(valueInt);
    }
    
    /********************************************************/
    //以下解析XML属性方法
    /********************************************************/
    
    /** 获取XML中属性字段 */
    public static String getString(String xml, String name) throws Exception
    {
        String lField = name + "=\"";
        String rField = "\"";
        int iLeft = xml.indexOf(lField);
        if (iLeft == -1)
            return null;
        
        int iRight = xml.indexOf(rField, iLeft+lField.length());
        if (iRight == -1)
            return null;
        
        return xml.substring(iLeft+lField.length(), iRight);
    }
    
    /** 获取XML中属性字段 */
    public static int getInt(String xml, String name) throws Exception
    {
        String value = getString(xml, name);
        if (value == null)
            throw new Exception("未找到字段值");
        
        return Integer.parseInt(value);
    }
    
    /** 获取XML中属性字段 */
    public static long getLong(String xml, String name) throws Exception
    {
        String value = getString(xml, name);
        if (value == null)
            throw new Exception("未找到字段值");
        
        return Long.parseLong(value);
    }
    

    /** 获取XML中属性列表 */
    public static List<String> getList(String xml, String name)
    {
        List<String> list = new ArrayList<String>();
        
        String lField = "<"+name+" ";
        String rField = "</"+name+">";
        String rField2 = "/>";
        
        for(int iLeft=xml.indexOf(lField);iLeft!=-1;iLeft=xml.indexOf(lField))
        {
            int len = rField.length();
            int iRight = xml.indexOf(rField, iLeft);
            if (iRight == -1)
            {
                iRight = xml.indexOf(rField2, iLeft);
                len = rField2.length();
            }
            
            if (iRight == -1)
                break;
            
            String str = xml.substring(iLeft, iRight+len);
            list.add(str);
            xml = xml.substring(iRight+len);
        }
        
        return list;
    }
}
